package org.hagopa.games.moneypool.game;

import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.hagopa.games.moneypool.Configuration;
import org.hagopa.games.moneypool.dblayer.GameGeneralInfoAdopt;

import org.hagopa.games.moneypool.dblayer.Connector.DBConnector;
import org.hagopa.games.moneypool.network.NetClientHandler;
import org.hagopa.games.moneypool.utils.CommonTracer;

public class GamesManager implements Runnable{
	private static long totalId = 1;
	private ConcurrentHashMap <Long, GameThread> GamesPool = new ConcurrentHashMap<Long, GameThread>();
	private ConcurrentLinkedQueue <NetClientHandler> waitingConnections = null;
	private CommonTracer cLogger = CommonTracer.getInstance();
        //DBCustomLogger
	
		
	public GamesManager(Configuration cfg)
	{
		System.out.println("[GamesManager](GamesManager) - DB Connect data");
		System.out.println("[GamesManager](GamesManager) - Host: "+ Configuration.getDBHost());
		System.out.println("[GamesManager](GamesManager) - User:" + Configuration.getUser());
		DBConnector nDB = DBConnector.getInstance();
		DBConnector.setInitialSettings(Configuration.getDBHost(),Configuration.getUser(), 
									Configuration.getPwd(), Configuration.getDbname());
		if(null == nDB)
		{
			System.out.println("[GamesManager](GamesManager) - Failed to create DB handler!!");
			return;
		}
		DBConnector.connect();
                cLogger.setEnableFlag(cfg.DBLogEnableFlag());
                this.cLogger.setLoggerType(1);
	}
	
	
	public void linkWaitingConnections(ConcurrentLinkedQueue <NetClientHandler> rcp)
	{
		this.waitingConnections = rcp;
		if(this.waitingConnections == null)
		{
			System.out.println("[GamesManager](linkWaitingConnections) - Failed to link Reception");
		}
		System.out.println("[GamesManager](linkWaitingConnections) - Num of Waiting connections in Reception : " + this.waitingConnections.size());
		
	}
	
	private void cleanupGameThreads()
	{
		Set <Long> games = this.GamesPool.keySet();
		Iterator<Long> it = games.iterator();
		while(it.hasNext())
		{
			GameThread tmp = this.GamesPool.get(it.next());
			if(tmp.isRunning() == false)
			{
				System.out.println("Remove Game, Id:" + tmp.getGameId());
				it.remove();
			}
		}
	}
	
        @Override
	public void run() {
		// TODO Auto-generated method stub
		Thread.currentThread().setName("BogoGameManagerThread");
		System.out.println("[GamesManager](run) - Games Manager Thread Started!!!\n---------------------------------------------\n");
		while(true)
		{
			//if(this.newGameReqQ.isEmpty())
			//	continue;
			cleanupGameThreads();
			NetClientHandler tmpClient = null;
			
			if(waitingConnections.isEmpty()) 
			{
				continue;
			}
			System.out.println("\n[GamesManager](run) - WaitingConnections size: " + this.waitingConnections.size());
			System.out.println("\n[GamesManager](run) - WE Have some waiting connections\n");
			//may be blocking!!!!!!!
			tmpClient = this.waitingConnections.remove();
		
			if(tmpClient != null)
			{
													
				//PlayerDataAdopt pda = new PlayerDataAdopt(tmpClient.getClientId());
				PlayerHolder pltmp = null;
				//if(true == pda.requestDB())
				//{
                                    pltmp = new PlayerHolder(tmpClient.getClientId());
                                    System.out.println("[GamesManager](run) - new player Id: " + pltmp.getGId());

                                    pltmp.setType(1);
                                    pltmp.setClientHandler(tmpClient, true);
                                    System.out.println("[GamesManager](run) - new player ClientId: " + ((NetClientHandler)pltmp.getClientHandler()).getClientId());
                                    GameThread tmpGame = CreateNewGame(tmpClient.getGameId());
                                    //tmpGame.getClass();
                                    //may be blocking!!!!!!!
                                    tmpGame.appendPlayerToGame(pltmp);
					
				//}
			}
			
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	
	private GameThread CreateNewGame(long gameId)
	{
		
		if( this.GamesPool.containsKey(gameId) == true)
		{
			return this.GamesPool.get(gameId);
		}
		else
		{
			GameGeneralInfoAdopt gdt = new GameGeneralInfoAdopt(gameId);
			gdt.requestDB();
			GamesManager.totalId++;
                        System.out.println("[GamesManager](CreateNewGame) - new gameId:" + GamesManager.totalId);
			GameThread tgm = new GameThread(GamesManager.totalId, gdt);
			this.GamesPool.put(new Long(gdt.getGame_id()), tgm);
			Thread GThread = new Thread(tgm);
			GThread.start();
			return tgm;
		}
	
	}
	
	
	public void stopAll()
	{
		DBConnector.disconnect();
		Set <Long> keys = this.GamesPool.keySet();
		Iterator<Long> it = keys.iterator();
		while(it.hasNext())
		{
			GameThread tmp = this.GamesPool.get(it.next());
			tmp.stop(1);
		}
	}

}